const User = require('../models/users')

const dayjs = require('dayjs')
const jwt = require('jsonwebtoken');
const Redis = require('ioredis');
const redis = new Redis(); // 默认连接到 localhost:6379

class User_C {
    // 用户登录
    static login = (req, res) => {
        console.log(req.body) //  -----undefined 
        let { username, password } = req.body;
        if (!username && !password) {
            res.status(400).json({ code: -2, msg: "参数错误：缺少必要的参数" })
        }
        // 加密密码
        // const saltRounds = 10; // 盐值轮数
        // bcrypt.genSalt(saltRounds, (err, salt) => {
        //     if (err) throw err;
        //     bcrypt.hash(password, salt, (err, hash) => {
        // if (err) throw err;
        // 将hash存储到数据库中
        // console.log('加密后的密码：', hash);
        User.login(username, password, (error, result) => {
            if (error) {
                console.log(error);
                res.status(422).json({ code: -1, msg: error, result: null, token: null });
            } else {
                const token = jwt.sign(
                    {
                        id: result[0].id,
                        username: result[0].username
                    },
                    '39qw89r23890', // 自定义密钥
                    {
                        expiresIn: '24h' // 过期时间
                    }
                );
                console.log(token);
                // res.json({ code: 0, msg: "登录成功！", data: { userInfo: { ...result[0] }, token } });
                // 切记：这里名字能带空格会出错的
                let key = `uid:${result[0].id}`
                redis.setex(key, 86400, token, (error, reslut) => {
                    if (error) {
                        console.log(error)
                        return res.status(500).json({ code: 500, msg: "操作redis时出错了" });
                    }
                    res.json({ code: 0, msg: "登录成功！", data: { userInfo: { ...result[0] }, token } });
                })
            }
        });
    }
    static async findByPk(req, res) {
        const { id } = req.query
        try {
            const results = await User.findByPk(id)
            res.json({
                code: 0,
                msg: "服务器请求成功",
                results: results
            })
        } catch (error) {
            res.json({ code: -1, msg: "服务器请求失败", error })
        }
    }
    static async findByUsername(req, res) {
        const { username } = req.query
        try {
            const results = await User.findByUsername(username)
            res.json({
                code: 0,
                msg: "服务器请求成功",
                results: results
            })
        } catch (error) {
            res.json({ code: -1, msg: "服务器请求失败", error })
        }
    }
    static async create(req, res) {
        const { username, password, email, role_id } = req.body
        const created_at = dayjs().format('YYYY-MM-DD HH:mm:ss');
        try {
            const results = await User.create(created_at, username, password, email, role_id)
            res.json({
                code: 0,
                msg: "服务器请求成功",
                results: results
            })
        } catch (error) {
            res.json({ code: -1, msg: "服务器请求失败", error })
        }
    }
    // 用户的列表
    static async list(req, res) {
        const { userrole, username, page, page_size } = req.query
        if (!page && !page_size) {
            res.json({
                code: -1,
                msg: "缺少必要的参数",
            })
        }
        try {
            const results = await User.userlist(userrole, username, Number(page), Number(page_size))
            res.json({
                code: 0,
                msg: "服务器请求成功",
                results: results
            })
        } catch (error) {
            res.json({ code: -1, msg: "服务器请求失败", error })
            console.log(error)
        }
    }
    // 用户的删除--真删除
    static async delete_t(req, res) {
        let { id } = req.query
        let p = User.deleteuser_t(id)
        p.then((results) => {
            console.log(results)
            res.json({ code: 0, msg: "用户删除成功！", results })
        }).catch((error) => {
            console.log(error)
            res.json({ code: -1, msg: "用户删除失败！", error })
        })
    }
    // 用户的修改保存数据
    static async edit_set_c(req, res) {
        // validator表单验证
        // const errors = validationResult(req);
        // if (!errors.isEmpty()) {
        //     return res.status(422).json({ errors: errors.array() });
        // }
        // 其他内容
        // 当前时间戳
        // let update_time = Date.now()
        const update_time = dayjs().format('YYYY-MM-DD HH:mm:ss');
        let { id, username, email, role_id } = req.body
        let p = User.edit_set(Number(id), username, email, role_id, update_time)
        p.then((results) => {
            console.log(results)
            res.json({ code: 0, msg: "用户修改保存成功！", results })
        }).catch((error) => {
            console.log(error)
            res.json({ code: -1, msg: "用户修改保存失败！", error })
        })
    }
    // 查看用户对应的权限
    static async userPermiss(req, res) {
        const userid = req.user.id
        try {
            const results = await User.userPermiss(userid)
            res.json({
                code: 0,
                msg: "服务器请求成功",
                results: results
            })
        } catch (error) {
            res.json({ code: -1, msg: "服务器请求失败", error })
        }
    }
    // 检查token是否过期
    static checkToken = (req, res, next) => {
        const authHeader = req.headers.authorization;
        const token = authHeader ? authHeader.split(' ')[1] : null;
        console.log(token)
        try {
            // 第一步：直接解码 Token（不验证签名和过期时间）
            const decoded = jwt.decode(token, { complete: true });
            if (!decoded) {
                return res.status(401).json({ status: 401, message: "无效的token格式" });
            }

            // 第二步：获取用户 ID（即使 Token 过期也能拿到）
            const { id } = decoded.payload;
            const key = `uid:${id}`;

            // 第三步：手动检查 Token 是否过期
            try {
                // 重新验证 Token（包含过期检查），但忽略结果，只为捕获错误
                jwt.verify(token, '39qw89r23890', { ignoreExpiration: true });
            } catch (verifyError) {
                if (verifyError instanceof jwt.TokenExpiredError) {
                    // 记录过期状态，但继续检查 Redis
                    console.log('Token 已过期，但继续检查 Redis 状态');
                } else {
                    // 其他错误（如签名无效）
                    throw verifyError;
                }
            }

            // 第四步：查询 Redis 中的 Token
            redis.get(key, (err, storedToken) => {
                if (err) {
                    console.error('Redis 错误:', err);
                    return res.status(500).json({ status: 500, message: "服务器内部错误" });
                }

                if (storedToken === token) {
                    // Token 有效（即使 JWT 过期但 Redis 中仍有效，可放行或按业务逻辑处理）
                    // next();
                    res.status(200).json({
                        status: 200,
                        message: "当前身份验证未失效！"
                    });
                } else {
                    res.status(403).json({
                        status: 403,
                        message: "token已失效，请重新登录！"
                    });
                }
            });

        } catch (error) {
            // 处理其他 JWT 错误（如篡改）
            if (error instanceof jwt.JsonWebTokenError) {
                return res.status(401).json({
                    status: 401,
                    message: "无效的token"
                });
            }
            next(error);
        }
    };
    // 退出登录
    static logout = (req, res) => {
        // 从请求头中获取Authorization字段，并提取token
        const authHeader = req.headers.authorization;
        const token = authHeader ? authHeader.split(' ')[1] : null; // 提取token
        if (!token) {
            return res.status(401).json({ code: 401, msg: "未提供token" });
        }
        const decoded = jwt.verify(token, '39qw89r23890');
        const { id } = decoded;
        let key = `uid:${id}`

        redis.del(key, (error, result) => {
            if (error) {
                console.log(error)
                return res.status(500).json({ code: 500, msg: "操作redis时出错了" });
            }
            res.json({ code: 0, msg: "退出登录成功！" });
        })
    }
}


module.exports = User_C